Skip to content

Removing almost unused ConsoleExtensions - #2103

Merged
adamsitnik merged 4 commits into
dotnet:mainfrom
adamsitnik:console
Mar 18, 2023
Merged

Removing almost unused ConsoleExtensions#2103
adamsitnik merged 4 commits into
dotnet:mainfrom
adamsitnik:console

Conversation

@adamsitnik

@adamsitnik adamsitnik commented Mar 17, 2023

Copy link
Copy Markdown
Member

It's a first step toward replacing IConsole with TextWriter Out and TextWriter Error (introducing IConsole to BCL would be currently impossible)

fixes #1851

@adamsitnik
adamsitnik requested review from Keboo and jonsequitur March 17, 2023 16:39
Comment on lines +21 to +24
catch (PlatformNotSupportedException)
{
_colorsAreSupported = false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly this should assume colors are supported if console redirection cannot be checked. See #1851.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 908accd, ConsoleExtensions was changed so that, if Platform.IsWasm, then it sets Console.ForegroundColor without checking Console.IsOutputRedirected. In dotnet/runtime#35555 however, IsOutputRedirectedCore() returns false without throwing, whereas ForegroundColor throws PlatformNotSupportedException. So the original wasm logic in ConsoleExtensions doesn't seem necessary any more, although I did not test.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only PlatformNotSupportedException-throwing IsOutputRedirectedCore method seems to be in https://github.com/dotnet/runtime/blob/30b879924a47d8660d5f4b14ff581ce40ae076f2/src/libraries/System.Console/src/System/ConsolePal.Wasi.cs, in which ForegroundColor likewise throws PlatformNotSupportedException. So okay, it's correct to assume colors are not supported if IsOutputRedirected throws.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KalleOlaviNiemitalo thank you for your feedback, I've changed the code so it checks the OS first, then the IsOutputRedirected which won't throw after the OS check

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which of those OS checks returns true on WASI?

private static bool GetColorsAreSupported()
#if NET7_0_OR_GREATER
=> !(OperatingSystem.IsBrowser() || OperatingSystem.IsAndroid() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS())
#else
=> !(RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))
|| RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID"))
|| RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS"))
|| RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")))
#endif
&& !Console.IsOutputRedirected;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "browser" checks are WASM checks:

OperatingSystem.IsBrowser(), RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")

@KalleOlaviNiemitalo

Copy link
Copy Markdown

This then fixes #1851.

Comment on lines 13 to +16
public override int Invoke(InvocationContext context)
{
context.Console.ResetTerminalForegroundColor();
context.Console.SetTerminalForegroundRed();
ConsoleHelpers.ResetTerminalForegroundColor();
ConsoleHelpers.SetTerminalForegroundRed();

@KalleOlaviNiemitalo KalleOlaviNiemitalo Mar 17, 2023

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an application is designed to parse and invoke commands from custom sources like network sockets, and it should not modify System.Console.ForegroundColor during these operations (because such changes might mess up output from a different thread), then it apparently needs to avoid UseParseErrorReporting entirely and avoid UseExceptionHandler with the default handler. That's tolerable but not quite obvious.

If you're eventually going to have TextWriter Error, then perhaps you can compare Error == System.Console.Error and change Console.ForegroundColor only in that matches. Or have some bool AllowConsoleColor property in CommandLineConfiguration.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking on — if class CliConfiguration is going to have TextWriter Error, then it can have bool UseErrorColor { get; set; } such that…

  • If UseErrorColor has not been set, then its getter computes the value from this.Error == System.Console.Error && !System.Console.IsErrorRedirected, defaulting to false on PlatformNotSupportedException. Does not cache the result into a field of CliConfiguration because it's going to be used only once per error. Instead, each method that reads this property should save the result to a local so that it restores the colours if and only if it has set them.
  • If UseErrorColor has been set, then trust the application-assigned value when deciding whether to set the foreground color, and do not check whether error has been redirected.

Not sure about IsErrorRedirected vs. IsOutputRedirected. The error text should go to the CliConfiguration.Error TextWriter, but if System.Console.ForegroundColor outputs ECMA-48 control sequences instead of using the Windows console API, I guess it cannot be told whether those should go to Console.Error or Console.Out. So perhaps the UseErrorColor getter should check this.Error == System.Console.Error && !System.Console.IsErrorRedirected && !System.Console.IsOutputRedirected. I'm omitting this.Out == System.Console.Out because errors should never go to this.Out.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When https://github.com/dotnet/runtime/blob/5edef4b20babd4c3ddac7460e536f86fd0f2d724/src/libraries/System.Console/src/System/ConsolePal.Unix.cs sets colors, it does lock (Console.Out) but writes to STDOUT_FILENO. So Console.SetOut(TextWriter) affects the locking but does not affect where the SGR control sequence goes.

…er colors are supported: check OS first (in non-throwing way), then check IsOutputRedirected which won't throw at this point
@adamsitnik adamsitnik mentioned this pull request Mar 18, 2023
@adamsitnik
adamsitnik merged commit 9ebcd90 into dotnet:main Mar 18, 2023
@adamsitnik
adamsitnik deleted the console branch March 18, 2023 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redundant logic in ConsoleExtensions

4 participants